{
  "openapi": "3.1.0",
  "info": {
    "title": "API de Recursos Compartilhados",
    "description": "APIs de gerenciamento de recursos compartilhados para proxies, grupos e tags. Esses recursos são usados tanto por Perfis de Navegador quanto por Telefones em Nuvem. URL base: `http://127.0.0.1:40000`",
    "version": "2026-09-05"
  },
  "tags": [
    {
      "name": "Proxies",
      "description": "APIs relacionadas a Proxies."
    },
    {
      "name": "Groups",
      "description": "APIs relacionadas a Groups."
    },
    {
      "name": "Tags",
      "description": "APIs relacionadas a Tags."
    },
    {
      "name": "Webhooks",
      "description": "APIs para a configuração do webhook da equipe."
    }
  ],
  "paths": {
    "/api/proxyInfo/page": {
      "post": {
        "summary": "Obtendo uma lista de proxies",
        "deprecated": false,
        "description": "Lista as configurações de proxy da equipe, página por página.\n- **Efeito**: nenhum. Somente leitura. É seguro repetir com recuo limitado.\n- **Observação**: as senhas são omitidas para membros comuns e para proxies na nuvem e dinâmicos. Os proxies dinâmicos aparecem aqui, mas são gerenciados em outro lugar e não podem ser editados pelos endpoints de proxy.",
        "operationId": "queryProxyInfoPageUsingPOST",
        "tags": [
          "Proxies"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^\\d+$",
                    "description": "ID de proxy opcional para correspondência exata. Envie o ID de 64 bits como string decimal para evitar perda de precisão. Omita para consultar sem filtro por ID. Os demais filtros e a paginação continuam sendo aplicados.",
                    "example": "1800000000000101"
                  },
                  "pageNo": {
                    "type": "integer",
                    "description": "Número da página atual (começa em 1)",
                    "example": 1
                  },
                  "pageSize": {
                    "type": "integer",
                    "description": "Número de itens por página",
                    "example": 10
                  },
                  "isCloudPhoneProxy": {
                    "type": "boolean",
                    "description": "Indica se o proxy é para uso em telefones na nuvem.\n- `true`: Excluir IPs locais/privados (por exemplo, 127.0.0.1, 360, pia, intervalos privados)\n- `false`: Retornar todos os proxies\n",
                    "example": false
                  },
                  "proxyCategoryType": {
                    "type": "integer",
                    "description": "Tipo de categoria de proxy:\n- `1` = Plataforma em nuvem\n- `2` = IP próprio\n",
                    "example": 2
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "Filtrar por endereço IP do proxy (correspondência parcial)",
                    "example": ""
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "Filtrar por nome de proxy (correspondência parcial)",
                    "example": ""
                  },
                  "proxyProviders": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Lista de IDs de tipos de dispositivo de proxy. Valores suportados:\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n- `4` = Oxylabs\n- `5` = Proxys.io\n- `6` = GeoSurf\n- `7` = Luminati\n- `8` = Lumauto\n- `9` = Oxylabsauto\n- `10` = Trojan\n- `11` = Shadowsocks\n- `12` = vmess\n- `13` = ABCPROXY\n- `14` = LunaProxy\n- `15` = IPHTML\n- `16` = PiaProxy\n- `17` = 922S5\n\n-",
                    "example": []
                  },
                  "proxyStatus": {
                    "type": "integer",
                    "description": "Status da atribuição de proxy:\n- `0` = Normal\n- `1` = Não atribuído\n- `2` = Em atualização\n- `3` = Expirado\n- `4` = Expirando em breve\n> Observação: Proxies de propriedade do usuário sempre usam o status `1`.\n",
                    "example": 1
                  },
                  "proxyCheckStatus": {
                    "type": "integer",
                    "description": "Status da verificação de integridade do proxy:\n- `0` = Pendente\n- `1` = Sucesso\n- `2` = Falha\n- `3` = Erro desconhecido\n",
                    "example": 1
                  },
                  "proxyTypes": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Tipos de protocolo proxy:\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n",
                    "example": []
                  }
                },
                "required": []
              },
              "example": {
                "id": "1800000000000101",
                "pageNo": 1,
                "pageSize": 10,
                "isCloudPhoneProxy": false,
                "proxyCategoryType": 2,
                "proxyIp": "",
                "proxyName": "",
                "proxyProviders": [],
                "proxyStatus": 1,
                "proxyCheckStatus": 1,
                "proxyTypes": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso. `data.dataList` contém os registros da página solicitada e é um array vazio quando não há correspondências; `data.total`, `data.current` e `data.pages` descrevem a paginação.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Código de resultado retornado: 0: Normal. Outros códigos são exceções.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Mensagem de erro",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current": {
                          "type": "string"
                        },
                        "dataList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "expiryTime": {
                                "description": "Tempo de validade",
                                "type": "string"
                              },
                              "id": {
                                "description": "Chave primária",
                                "type": "string"
                              },
                              "proxyCategoryType": {
                                "description": "Tipo de proxy 1: Proxy de plataforma; 2: Proxy próprio",
                                "type": "integer"
                              },
                              "proxyCheckStatus": {
                                "description": "Status da detecção: 0 - detecção pendente; 1 - monitoramento bem-sucedido; 2 - falha na detecção; 3 - erro desconhecido.",
                                "type": "integer"
                              },
                              "state": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Estado ou província do proxy. Prioriza a localização detectada do IP de saída e depois a configurada; pode ser null ou uma string vazia.",
                                "example": "California"
                              },
                              "city": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Cidade do proxy. Prioriza a localização detectada do IP de saída e depois a configurada; pode ser null ou uma string vazia.",
                                "example": "Los Angeles"
                              },
                              "proxyPort": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "format": "int32",
                                "description": "Porta de conexão do proxy; não é deduzida do nome. Pode ser null se indisponível.",
                                "example": 1080
                              },
                              "proxyIp": {
                                "description": "IP do proxy",
                                "type": "string"
                              },
                              "exportIp": {
                                "description": "exportar IP",
                                "type": "string"
                              },
                              "countryCode": {
                                "description": "código do país",
                                "type": "string"
                              },
                              "proxyName": {
                                "description": "Nome do proxy",
                                "type": "string"
                              },
                              "proxyProvider": {
                                "description": "Tipo de proxy: valor padrão 0-HTTP 1-HTTPS 2-SOCKS5 3-SSH 4-Oxylabs 5-Proxys.io 7-Luminati 8-Lumauto 9-Oxylabsauto 10-Trojan, 11-Shadowsocks 13-ABCPROXY 14-LunaProxy 15-IPHTML 16-PiaProxy 17-922S5\n",
                                "type": "integer"
                              },
                              "proxyType": {
                                "description": "Tipo de proxy: 0-http 1-https 2-socks5 3-ssh",
                                "type": "integer"
                              },
                              "username": {
                                "description": "Nome de usuário do proxy",
                                "type": "string"
                              },
                              "password": {
                                "description": "Senha do proxy",
                                "type": "string"
                              },
                              "refreshUrl": {
                                "description": "URL de atualização do proxy",
                                "type": "string"
                              }
                            }
                          }
                        },
                        "pages": {
                          "type": "string"
                        },
                        "total": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "current",
                        "dataList",
                        "pages",
                        "total"
                      ]
                    },
                    "requestId": {
                      "description": "ID da solicitação de operação",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": {
                    "current": "1",
                    "dataList": [
                      {
                        "expiryTime": "2026-09-01 12:00:00",
                        "id": "1673823102599682",
                        "proxyCategoryType": 1,
                        "proxyCheckStatus": 1,
                        "state": "California",
                        "city": "Los Angeles",
                        "proxyPort": 1080,
                        "proxyIp": "string",
                        "exportIp": "9222",
                        "countryCode": "string",
                        "proxyName": "example-name",
                        "proxyProvider": 1,
                        "proxyType": 1,
                        "username": "example-name",
                        "password": "string",
                        "refreshUrl": "https://example.com/resource"
                      }
                    ],
                    "pages": "1",
                    "total": "1"
                  },
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/proxyInfo/add": {
      "post": {
        "summary": "Adicionando proxy",
        "deprecated": false,
        "description": "Cria uma configuração de proxy na equipe.\n- **Pré-requisitos**: `proxyPort` é obrigatório e precisa estar entre 1 e 65535, e `proxyProvider` precisa ser um serviço reconhecido.\n- **Efeito**: insere um registro de proxy e retorna o identificador dele, pronto para vincular a perfis. Nada é enviado ao serviço do proxy.\n- **Conclusão**: sincrônica.\n- **Nova tentativa**: **não há verificação de unicidade de nome nem de configuração.** Enviar o mesmo corpo duas vezes produz dois proxies com dois identificadores. Depois de um timeout, procure em `/proxyInfo/page` antes de reenviar.\n\nErros de negócio documentados: `14023`. Consulte [Error Codes](../Getting%20Started/error-codes.md) para o significado de cada código. Qualquer operação também pode retornar os códigos comuns.",
        "operationId": "addUsingPOST",
        "tags": [
          "Proxies"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "city": {
                    "type": "string",
                    "description": "Cidade",
                    "example": ""
                  },
                  "country": {
                    "type": "string",
                    "description": "Código do país (ISO 3166-1 alfa-2). Necessário apenas se proxyProvider=17.\n",
                    "example": "AD"
                  },
                  "encryptionType": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Tipo de criptografia, valores válidos são números inteiros de 1 a 14.",
                    "example": 14
                  },
                  "ipChangeAction": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Ação em caso de alteração de IP: 0 = Bloquear, 1 = Avisar",
                    "example": 1
                  },
                  "ipMonitor": {
                    "type": "boolean",
                    "description": "Ativar monitoramento de alterações de IP",
                    "example": false
                  },
                  "password": {
                    "type": "string",
                    "description": "Senha para autenticação de proxy",
                    "example": ""
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "Endereço IP do proxy",
                    "example": "8.10.22.46"
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "Nome do proxy (suporta marcadores como {{random}})",
                    "example": "sock5_{{random}}"
                  },
                  "proxyPort": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Número da porta do proxy",
                    "example": 65534
                  },
                  "proxyProvider": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Tipo de tipo de proxy:\n0=HTTP, 1=HTTPS, 2=SOCKS5, 3=SSH, 4=Oxylabs, 5=Proxys.io, 6=GeoSurf, 7=Luminati, 8=Lumauto, 9=Oxylabsauto, 10=Trojan, 11=Shadowsocks, 12=vmess, 13=ABCPROXY, 14=LunaProxy, 15=IPHTML, 16=PiaProxy, 17=922S5.\n\nRegras especiais:\n- Se proxyProvider for 7 ou 8, proxyType é obrigatório.\n- Se proxyProvider for 17, country é obrigatório; state e city são opcionais.\n",
                    "example": 2
                  },
                  "proxyType": {
                    "type": "integer",
                    "format": "int32",
                    "description": "Tipo de protocolo proxy: 0=HTTP, 1=HTTPS, 2=SOCKS5, 3=SSH.\nNecessário apenas quando proxyProvider for 7 ou 8.\n",
                    "example": 1
                  },
                  "refreshUrl": {
                    "type": "string",
                    "description": "URL para atualizar o IP do proxy dinâmico (se compatível)",
                    "example": ""
                  },
                  "state": {
                    "type": "string",
                    "description": "Estado/Província",
                    "example": ""
                  },
                  "username": {
                    "type": "string",
                    "description": "Nome de usuário para autenticação de proxy",
                    "example": ""
                  }
                },
                "required": [
                  "proxyIp",
                  "proxyPort",
                  "proxyProvider"
                ]
              },
              "example": {
                "proxyIp": "8.10.22.46",
                "proxyPort": 65534,
                "proxyProvider": 2,
                "proxyType": 1,
                "country": "AD",
                "state": "",
                "city": "",
                "encryptionType": 14,
                "ipChangeAction": 1,
                "ipMonitor": false,
                "proxyName": "sock5_{{random}}",
                "refreshUrl": "",
                "username": "",
                "password": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso. `data` é um único valor inteiro.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Código de resultado retornado: 0: Normal. Outros códigos são exceções.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Mensagem de erro",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "description": "ID do proxy",
                      "type": "integer"
                    },
                    "requestId": {
                      "description": "ID da solicitação de operação",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": 0,
                  "requestId": "abcd1234"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/proxyInfo/update": {
      "post": {
        "summary": "Modificando informações de proxy",
        "deprecated": false,
        "description": "Atualiza uma configuração de proxy.\n- **Pré-requisitos**: o proxy precisa existir na equipe. **Proxies dinâmicos não podem ser atualizados** por este endpoint. O serviço precisa ser um valor reconhecido.\n- **Efeito**: é uma sobrescrita completa, não um patch: os campos que você omitir voltam aos valores padrão em vez de manter os atuais. Leia o proxy primeiro e envie-o de volta completo.\n- **Propagação**: os perfis mantêm o vínculo porque só o registro do proxy muda, mas um navegador ou Cloud Phone que já esteja em execução continua usando os dados de conexão com que iniciou. Reinicie-o para adotar os novos.\n- **Conclusão**: sincrônica. Sem bloqueio otimista, então atualizações simultâneas são resolvidas pela última escrita.\n\nErros de negócio documentados: `14003`, `14023`. Consulte [Error Codes](../Getting%20Started/error-codes.md) para o significado de cada código. Qualquer operação também pode retornar os códigos comuns.",
        "operationId": "updateProxyUsingPOST",
        "tags": [
          "Proxies"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "proxyIp",
                  "proxyPort",
                  "proxyProvider"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "ID de proxy exclusivo"
                  },
                  "proxyIp": {
                    "type": "string",
                    "description": "Endereço IP do servidor proxy"
                  },
                  "proxyPort": {
                    "type": "integer",
                    "description": "Porta do servidor proxy"
                  },
                  "proxyName": {
                    "type": "string",
                    "description": "Nome personalizado para o proxy"
                  },
                  "country": {
                    "type": "string",
                    "description": "País (ex.: \"EUA\", \"CN\")"
                  },
                  "city": {
                    "type": "string",
                    "description": "Nome da cidade"
                  },
                  "username": {
                    "type": "string",
                    "description": "Nome de usuário para autenticação (se necessário)"
                  },
                  "password": {
                    "type": "string",
                    "description": "Senha de autenticação (se necessário)"
                  },
                  "proxyType": {
                    "type": "integer",
                    "description": "Tipo de protocolo proxy:\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n"
                  },
                  "proxyProvider": {
                    "type": "integer",
                    "description": "ID do tipo de proxy:\n- `0` = HTTP\n- `1` = HTTPS\n- `2` = SOCKS5\n- `3` = SSH\n- `4` = Oxylabs\n- `5` = Proxys.io\n- `6` = GeoSurf\n- `7` = Luminati\n- `8` = Lumauto\n- `9` = Oxylabsauto\n- `10` = Trojan\n- `11` = Shadowsocks\n- `12` = vmess\n- `13` = ABCPROXY\n- `14` = LunaProxy\n- `15` = IPHTML\n- `16` = PiaProxy\n- `17` = 922S5\n"
                  },
                  "encryptionType": {
                    "type": "integer",
                    "description": "Tipo de criptografia (específico do serviço, geralmente 0 para texto simples)"
                  },
                  "ipMonitor": {
                    "type": "boolean",
                    "description": "Ativar monitoramento de alterações de IP"
                  },
                  "ipChangeAction": {
                    "type": "integer",
                    "description": "Ação a ser tomada quando o IP muda:\n- `1` = Notificar / Atualizar (valor comum)\n> Consulte a documentação do sistema para obter todas as opções.\n"
                  },
                  "refreshUrl": {
                    "type": "string",
                    "description": "URL para acionar a atualização de IP (se compatível com o serviço)"
                  },
                  "state": {
                    "type": "string",
                    "description": "Campo reservado ou estado personalizado (opcional)"
                  }
                }
              },
              "example": {
                "id": "1566403036579198",
                "proxyIp": "108.11.23.85",
                "proxyPort": 4096,
                "proxyName": "MyProxy",
                "country": "US",
                "city": "New York",
                "username": "",
                "password": "",
                "proxyType": 0,
                "proxyProvider": 0,
                "encryptionType": 0,
                "ipMonitor": true,
                "ipChangeAction": 1,
                "refreshUrl": "",
                "state": ""
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso. Esta operação não retorna carga útil; o resultado é informado por `code`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Código de resultado retornado: 0: Normal. Outros códigos são exceções.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Mensagem de erro",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "requestId": {
                      "description": "ID da solicitação de operação",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "requestId": "efgh5678"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/proxyInfo/delete": {
      "post": {
        "summary": "Excluir proxy",
        "deprecated": false,
        "description": "Exclui uma ou mais configurações de proxy.\n- **Pré-requisitos**: pelo menos um identificador precisa ser resolvido dentro da equipe; os que não são resolvidos são ignorados em silêncio. **Um proxy de plataforma na nuvem que não expirou não pode ser excluído** e é informado com um erro específico.\n- **Efeito**: os proxies próprios são removidos e desvinculados de qualquer servidor de salto. Um proxy de plataforma na nuvem já expirado é, em vez disso, marcado para liberação, a assinatura dele é cancelada e o IP é liberado **de forma assíncrona**: a liberação pode ainda estar em andamento quando a resposta chega.\n- **Efeitos em cascata**: os perfis e os Cloud Phones vinculados ao proxy **não são bloqueados nem desvinculados**. Eles continuam apontando para o proxy excluído e as sessões em execução não são interrompidas. Revincule-os com `/env/setProxy/batch` antes de excluir.\n- **Nova tentativa**: os identificadores são processados um a um e a chamada é interrompida na primeira rejeição, então o lote pode ser aplicado parcialmente. Releia `/proxyInfo/page` antes de repetir.\n\nErros de negócio documentados: `14017`, `14024`. Consulte [Error Codes](../Getting%20Started/error-codes.md) para o significado de cada código. Qualquer operação também pode retornar os códigos comuns.",
        "operationId": "deleteProxyUsingPOST",
        "tags": [
          "Proxies"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int64"
                }
              },
              "example": [
                1054661322597744600,
                1054661322597744600
              ]
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso. Esta operação não retorna carga útil; o resultado é informado por `code`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Código de resultado retornado: 0: Normal. Outros códigos são exceções.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Mensagem de erro",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "requestId": {
                      "description": "ID da solicitação de operação",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "requestId": "ijkl9012"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envgroup/page": {
      "post": {
        "operationId": "apiEnvgroupPagePost",
        "summary": "Obtenha uma lista de grupos",
        "deprecated": false,
        "description": "Lista os grupos de perfis, página por página.\n- **Efeito**: nenhum. Somente leitura. É seguro repetir com recuo limitado.\n- **Observação**: quando a equipe autoriza o acesso por grupo, um membro que não tem nenhuma concessão de grupo recebe uma página vazia em vez de um erro.",
        "tags": [
          "Groups"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "groupName": {
                    "type": "string",
                    "title": "Nome do grupo (correspondência parcial)"
                  },
                  "pageNo": {
                    "type": "integer",
                    "title": "Página atual"
                  },
                  "pageSize": {
                    "type": "integer",
                    "title": "Itens por página"
                  }
                },
                "required": [
                  "groupName",
                  "pageNo",
                  "pageSize"
                ]
              },
              "example": {
                "groupName": "132-kernel",
                "pageNo": 1,
                "pageSize": 10
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso. `data.dataList` contém os registros da página solicitada e é um array vazio quando não há correspondências; `data.total`, `data.current` e `data.pages` descrevem a paginação.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Código de resultado retornado: 0: Normal. Outros códigos são exceções.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Mensagem de erro",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current": {
                          "type": "string"
                        },
                        "dataList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "description": "ID do grupo",
                                "type": "string"
                              },
                              "groupName": {
                                "description": "Nome do grupo",
                                "type": "string"
                              }
                            }
                          }
                        },
                        "pages": {
                          "type": "string"
                        },
                        "total": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "current",
                        "dataList",
                        "pages",
                        "total"
                      ]
                    },
                    "requestId": {
                      "description": "ID da solicitação de operação",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "current": "0",
                    "dataList": [
                      {
                        "id": "0",
                        "groupName": ""
                      }
                    ],
                    "pages": "0",
                    "total": "0"
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envgroup/edit": {
      "post": {
        "operationId": "apiEnvgroupEditPost",
        "summary": "Modificar informações de agrupamento",
        "deprecated": false,
        "description": "Renomeia um grupo de perfis.\n- **Pré-requisitos**: o grupo precisa existir na equipe, quem chama precisa ter autorização para ele, e o nome novo não pode colidir com outro grupo. A verificação de unicidade só é executada quando o nome realmente muda.\n- **Efeito**: renomeia o grupo. Os perfis permanecem nele: eles referenciam o grupo por identificador, então nada mais precisa ser atualizado.\n- **Conclusão**: sincrônica e idempotente.",
        "tags": [
          "Groups"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "groupName",
                  "id"
                ],
                "properties": {
                  "groupName": {
                    "type": "string",
                    "description": "Novo nome para o grupo ambientalista"
                  },
                  "id": {
                    "type": "string",
                    "description": "ID único do grupo a ser atualizado"
                  }
                }
              },
              "example": {
                "groupName": "Group-1574544945848579",
                "id": "1574525425557584"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso. `data` é um único valor booleano.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Código de resultado retornado: 0: Normal. Outros códigos são exceções.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Mensagem de erro",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean",
                      "description": "resultado"
                    },
                    "requestId": {
                      "description": "ID da solicitação de operação",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": true,
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envgroup/create": {
      "post": {
        "operationId": "apiEnvgroupCreatePost",
        "summary": "Adicionar grupo",
        "deprecated": false,
        "description": "Cria um grupo de perfis.\n- **Pré-requisitos**: o nome não pode estar vazio, admite no máximo 100 caracteres e não pode já estar em uso por um grupo da equipe. **Uma equipe é limitada a 1000 grupos.**\n- **Efeito**: cria o grupo. Quando a equipe autoriza o acesso por grupo e quem chama não é o proprietário, o acesso ao novo grupo também é concedido a quem chama.\n- **Conclusão**: sincrônica; `data` traz o identificador do novo grupo.\n- **Nova tentativa**: um nome duplicado é rejeitado em vez de reutilizar o grupo existente, então uma repetição depois de uma chamada que teve sucesso mas cuja resposta você não viu falha com um erro de nome duplicado; isso é sinal de que a primeira chamada funcionou. Confirme com `/envgroup/page`.",
        "tags": [
          "Groups"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "groupName"
                ],
                "properties": {
                  "groupName": {
                    "description": "Nome do grupo",
                    "type": "string"
                  }
                }
              },
              "example": {
                "groupName": "Group-333"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso. `data` é um objeto com os campos `id` e `groupName`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Código de resultado retornado: 0: Normal. Outros códigos são exceções.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Mensagem de erro",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "description": "Os dados retornados pela operação",
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "ID do grupo",
                          "type": "string"
                        },
                        "groupName": {
                          "description": "Nome do grupo",
                          "type": "string"
                        }
                      }
                    },
                    "requestId": {
                      "description": "ID da solicitação de operação",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": null,
                  "data": {
                    "id": "1673823102599682",
                    "groupName": "example-name"
                  },
                  "requestId": "0d8b6f1c-9f4e-4d02-9d1a-7c3f5a1b2c3d"
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envgroup/delete": {
      "post": {
        "operationId": "apiEnvgroupDeletePost",
        "summary": "Excluir grupo",
        "deprecated": false,
        "description": "Exclui um ou mais grupos de perfis.\n- **Pré-requisitos**: pelo menos um identificador precisa ser resolvido dentro da equipe e quem chama precisa ter autorização para ele; identificadores que não são resolvidos são ignorados em silêncio.\n- **Efeito**: exclui os grupos e as concessões de acesso de membros a eles. Os perfis de navegador e os Cloud Phones que estavam neles ficam sem grupo, então nenhuma referência órfã de grupo é deixada para trás. Ativar o indicador de excluir ambientes move, além disso, os perfis para os quais você tem autorização **para a lixeira**; eles não são destruídos, e os Cloud Phones nunca são afetados por esse indicador.\n- **Conclusão**: sincrônica, mas **não atômica**. O grupo é excluído primeiro e as etapas seguintes ainda podem falhar, por exemplo quando um perfil está em execução ou em transferência, deixando o grupo excluído e os perfis sem serem movidos.\n- **Nova tentativa**: verifique com `/envgroup/page` e a lista de perfis antes de repetir.\n\nErros de negócio documentados: `19064`. Consulte [Error Codes](../Getting%20Started/error-codes.md) para o significado de cada código. Qualquer operação também pode retornar os códigos comuns.",
        "tags": [
          "Groups"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "ID único do grupo a ser atualizado"
                  },
                  "isDeleteAllEnv": {
                    "type": "boolean",
                    "description": "Excluir os ambientes do grupo? false: não excluir; true: excluir"
                  }
                }
              },
              "example": {
                "ids": [
                  "string"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso. `data` é um único valor booleano.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Código de resultado retornado: 0: Normal. Outros códigos são exceções.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Mensagem de erro",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "ID da solicitação de operação",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envtag/all": {
      "get": {
        "operationId": "apiEnvtagAllGet",
        "summary": "Obtendo uma lista de tags",
        "deprecated": false,
        "description": "Retorna todas as etiquetas de perfil da equipe.\n- **Efeito**: nenhum. Somente leitura. É seguro repetir com recuo limitado.\n- **Observação**: este endpoint **não é paginado e as etiquetas não têm limite no servidor**, então a resposta cresce com o número de etiquetas que a sua equipe criou. Dimensione o seu cliente de acordo.",
        "tags": [
          "Tags"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sucesso. `data` é um array de objetos com os campos `id` e `tagName` e um array vazio quando não há nada a retornar.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Código de resultado retornado: 0: Normal. Outros códigos são exceções.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "mensagem de erro",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "ID das etiquetas",
                            "type": "string"
                          },
                          "tagName": {
                            "description": "Nome das etiquetas",
                            "type": "string"
                          }
                        }
                      }
                    },
                    "requestId": {
                      "description": "ID da solicitação de operação",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": [
                    {
                      "id": "0",
                      "tagName": ""
                    }
                  ],
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envtag/create": {
      "post": {
        "operationId": "apiEnvtagCreatePost",
        "summary": "Criar etiquetas",
        "deprecated": false,
        "description": "Cria uma etiqueta de perfil.\n- **Pré-requisitos**: o nome não pode estar vazio, admite no máximo 100 caracteres e não pode já estar em uso por uma etiqueta da equipe.\n- **Efeito**: cria a etiqueta e retorna o identificador dela. Diferente dos grupos, as etiquetas não têm limite de quantidade.\n- **Nova tentativa**: um nome duplicado é rejeitado em vez de reutilizar a etiqueta existente. Confirme com `/envtag/all`.",
        "tags": [
          "Tags"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "tagName"
                ],
                "properties": {
                  "tagName": {
                    "type": "string",
                    "description": "nome da tag"
                  }
                }
              },
              "example": {
                "tagName": "Tag-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso. `data` é um objeto com os campos `id` e `tagName`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Código de resultado retornado: 0: Normal. Outros códigos são exceções.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "mensagem de erro",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "description": "ID das etiquetas",
                          "type": "string"
                        },
                        "tagName": {
                          "description": "Nome das etiquetas",
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "tagName"
                      ]
                    },
                    "requestId": {
                      "description": "ID da solicitação de operação",
                      "type": "string"
                    },
                    "error": {
                      "type": "object",
                      "properties": {}
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "id": "0",
                    "tagName": ""
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envtag/edit": {
      "post": {
        "operationId": "apiEnvtagEditPost",
        "summary": "Modificar informações das etiquetas",
        "deprecated": false,
        "description": "Renomeia uma etiqueta de perfil.\n- **Pré-requisitos**: a etiqueta precisa existir na equipe e o nome novo não pode colidir com outra etiqueta.\n- **Efeito**: renomeia a etiqueta. Os vínculos existentes não são afetados e os perfis mostram o nome novo imediatamente.\n- **Conclusão**: sincrônica e idempotente.",
        "tags": [
          "Tags"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "tagName"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "ID da tag"
                  },
                  "tagName": {
                    "type": "string",
                    "description": "nome da tag"
                  }
                }
              },
              "example": {
                "id": "1564715845550177",
                "tagName": "Updated-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso. `data` é um único valor booleano.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Código de resultado retornado: 0: Normal. Outros códigos são exceções.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Mensagem de erro",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "ID da solicitação de operação",
                      "type": "string"
                    },
                    "error": {
                      "type": "object",
                      "properties": {}
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/envtag/delete": {
      "post": {
        "operationId": "apiEnvtagDeletePost",
        "summary": "Excluir etiquetas",
        "deprecated": false,
        "description": "Exclui uma ou mais etiquetas de perfil.\n- **Pré-requisitos**: pelo menos um identificador precisa ser resolvido dentro da equipe; os que não são resolvidos são ignorados em silêncio.\n- **Efeito**: exclui as etiquetas. A etiqueta desaparece de todos os perfis que a carregavam, e nenhum perfil é excluído. Este endpoint gerencia apenas etiquetas de perfil: as etiquetas de arquivo do Cloud Storage são gerenciadas separadamente.\n- **Conclusão**: sincrônica. Uma chamada repetida informa que as etiquetas são inválidas, o que significa que a primeira teve sucesso.\n\nErros de negócio documentados: `19105`. Consulte [Error Codes](../Getting%20Started/error-codes.md) para o significado de cada código. Qualquer operação também pode retornar os códigos comuns.",
        "tags": [
          "Tags"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "ID único da tag a ser atualizada"
                  }
                }
              },
              "example": {
                "ids": [
                  "string"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso. `data` é um único valor booleano.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Código de resultado retornado: 0: Normal. Outros códigos são exceções.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Mensagem de erro",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "description": "ID da solicitação de operação",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": true,
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    },
    "/api/webhook/config": {
      "post": {
        "operationId": "apiWebhookConfigPost",
        "summary": "Configurar o webhook da equipe",
        "deprecated": false,
        "description": "Cria ou substitui a configuração de webhook da equipe.\n\n- **Pré-requisitos**: `callbackUrl` deve ser uma URL HTTPS de 1 a 1024 caracteres, com host, sem informações de usuário, sem fragmento e com porta válida. Todos os endereços para os quais ela resolver precisam ser roteáveis publicamente; faixas de localhost, privadas, link-local, CGNAT, metadados de nuvem, reservadas por protocolo, de documentação e 6to4 são rejeitadas. A mesma verificação ocorre de novo quando uma entrega abre a conexão, então um nome que depois resolva para uma faixa privada faz aquela entrega falhar em vez de alcançar sua rede.\n- **Efeito**: faz upsert da única configuração da equipe do contexto do servidor. `teamId` nunca é lido da requisição, então quem chama não pode configurar outra equipe. Os endpoints da Local API e da Open API leem e gravam o mesmo registro, e a resposta reflete o que foi armazenado.\n- **Desativação**: `enabled: false` mantém a URL e interrompe a criação de novos eventos. Eventos já na fila são cancelados um a um se a configuração ainda estiver desativada quando forem autorizados, então reativar logo permite que continuem.\n- **Repetição**: seguro. O salvamento é um upsert por equipe, então repetir a mesma requisição converge para o mesmo estado.\n- **Versão do cliente**: requer o cliente MoreLogin v2.66.0 ou superior, porque é o cliente de desktop que expõe essa rota localmente. O endpoint da Open API não depende do cliente.\n\nConsulte [Webhooks](../Getting%20Started/webhooks.md) para o contrato de callback, os nomes de evento e a programação de novas tentativas.\n\nErros de negócio documentados: `41001`. Consulte [Error Codes](../Getting%20Started/error-codes.md) para o significado de cada código. Qualquer operação também pode retornar os códigos comuns.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "callbackUrl": {
                    "description": "URL HTTPS que recebe os eventos. De 1 a 1024 caracteres.",
                    "type": "string",
                    "maxLength": 1024
                  },
                  "enabled": {
                    "description": "Indica se a entrega está ativada para a equipe.",
                    "type": "boolean"
                  }
                },
                "required": [
                  "callbackUrl",
                  "enabled"
                ]
              },
              "example": {
                "callbackUrl": "https://example.com/morelogin/webhook",
                "enabled": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso. `data` é um objeto com os campos `callbackUrl` e `enabled`, refletindo a configuração armazenada.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "description": "Código de resultado. `0` indica sucesso; outros códigos indicam exceções.",
                      "type": "integer"
                    },
                    "msg": {
                      "description": "Mensagem de erro",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "callbackUrl": {
                          "description": "A URL HTTPS de callback armazenada.",
                          "type": "string"
                        },
                        "enabled": {
                          "description": "Indica se a entrega está ativada para a equipe.",
                          "type": "boolean"
                        }
                      }
                    },
                    "requestId": {
                      "description": "ID da solicitação da operação",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "msg",
                    "data",
                    "requestId"
                  ]
                },
                "example": {
                  "code": 0,
                  "msg": "",
                  "data": {
                    "callbackUrl": "https://example.com/morelogin/webhook",
                    "enabled": true
                  },
                  "requestId": ""
                }
              }
            },
            "headers": {}
          }
        },
        "security": []
      }
    }
  },
  "webhooks": {},
  "components": {
    "securitySchemes": {}
  },
  "servers": [
    {
      "url": "http://127.0.0.1:40000",
      "description": "Endpoint local do MoreLogin"
    }
  ],
  "security": []
}